package com.wxzz.elearing.user.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.wxzz.elearing.user.dto.EnterprisePermissionDto;
import com.wxzz.elearing.user.entity.*;
import com.wxzz.elearing.user.mapper.*;
import com.wxzz.elearing.user.service.IAdminPermissionService;
import com.wxzz.elearing.user.service.IAdminRoleService;
import com.wxzz.elearning.common.constants.RedisConstants;
import com.wxzz.elearning.common.vo.ReturnVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author
 * @since 2021-03-11
 */
@Service
public class AdminPermissionServiceImpl extends ServiceImpl<AdminPermissionMapper, AdminPermission> implements IAdminPermissionService {


    @Autowired
    private AdminPermissionMapper adminPermissionMapper;

    @Autowired
    private AdminPermissionDisabledMapper adminPermissionDisabledMapper;

    @Override
    public ReturnVO<List<AdminPermission>> listAdminPermission(Long enterpriseId) {
        List<AdminPermission> adminPermissions = null;
        if (enterpriseId == 0) {
            //总后台权限列表
            adminPermissions = adminPermissionMapper.listAdminPermissions(0);
        } else {
            //企业后台权限列表
            adminPermissions = adminPermissionMapper.listAdminPermissions(1);
        }

        //查询被禁用的权限
        List<Long> disabledIds = adminPermissionDisabledMapper.selectAdminPermissionDisabledByEnterpriseId(enterpriseId);
        removePermissions(adminPermissions, disabledIds);
        for (AdminPermission adminPermission : adminPermissions) {
            //二级菜单
            List<AdminPermission> secondPermissions = adminPermissionMapper.selectAdminPermissionByPid(adminPermission.getId());
            removePermissions(secondPermissions, disabledIds);
            adminPermission.setChildren(secondPermissions);
            for (AdminPermission secondPermission : secondPermissions) {
                //按钮权限
                List<AdminPermission> buttonPermissions = adminPermissionMapper.selectAdminPermissionByPid(secondPermission.getId());
                removePermissions(buttonPermissions, disabledIds);
                secondPermission.setChildren(buttonPermissions);
                //子集按钮
                for (AdminPermission buttonPermission : buttonPermissions) {
                    List<AdminPermission> buttonPermissionChildrens = adminPermissionMapper.selectAdminPermissionByPid(buttonPermission.getId());
                    buttonPermission.setChildren(buttonPermissionChildrens);
                }
            }
        }
        return new ReturnVO<>("权限列表查询成功", adminPermissions);
    }

    @Override
    public ReturnVO<List<AdminPermission>> listAllAdminPermission() {
        List<AdminPermission> adminPermissions = adminPermissionMapper.listAdminPermissions(1);
        for (AdminPermission adminPermission : adminPermissions) {
            //二级菜单
            List<AdminPermission> secondPermissions = adminPermissionMapper.selectAdminPermissionByPid(adminPermission.getId());
            adminPermission.setChildren(secondPermissions);
            for (AdminPermission secondPermission : secondPermissions) {
                //按钮权限
                List<AdminPermission> buttonPermissions = adminPermissionMapper.selectAdminPermissionByPid(secondPermission.getId());
                secondPermission.setChildren(buttonPermissions);
                //子集按钮
                for (AdminPermission buttonPermission : buttonPermissions) {
                    List<AdminPermission> buttonPermissionChildrens = adminPermissionMapper.selectAdminPermissionByPid(buttonPermission.getId());
                    buttonPermission.setChildren(buttonPermissionChildrens);
                }
            }
        }
        return new ReturnVO<>("权限列表查询成功", adminPermissions);
    }

    @Autowired
    private AdminUserMapper adminUserMapper;

    @Autowired
    private AdminRoleMapper adminRoleMapper;

    @Override
    public ReturnVO saveEnterpriseAdminPermission(EnterprisePermissionDto enterprisePermissionDto) {
        //先删除原来的权限
        adminPermissionDisabledMapper.delete(new LambdaQueryWrapper<AdminPermissionDisabled>()
                .eq(AdminPermissionDisabled::getEnterpriseId, enterprisePermissionDto.getEnterpriseId()));
        if (enterprisePermissionDto.getIds() != null) {
            //查询所有企业权限
            List<AdminPermission> permissions = adminPermissionMapper.selectList(new LambdaQueryWrapper<AdminPermission>()
                    .eq(AdminPermission::getPermissionType, 1));
            //筛选出禁用的权限
            removePermissions(permissions, enterprisePermissionDto.getIds());
            for (AdminPermission permission : permissions) {
                AdminPermissionDisabled adminPermissionDisabled = new AdminPermissionDisabled();
                adminPermissionDisabled.setEnterpriseId(enterprisePermissionDto.getEnterpriseId());
                adminPermissionDisabled.setAdminPermissionId(permission.getId());
                adminPermissionDisabledMapper.insert(adminPermissionDisabled);
            }
        }
        //查询企业的admin角色
        AdminRole adminRole = adminRoleMapper.selectOne(new LambdaQueryWrapper<AdminRole>()
                .eq(AdminRole::getEnterpriseId, enterprisePermissionDto.getEnterpriseId())
                .eq(AdminRole::getRoleType, 1));
        //查询所有权限
        List<AdminPermission> permissions = adminPermissionMapper.selectList(new LambdaQueryWrapper<AdminPermission>()
                .eq(AdminPermission::getPermissionType, 1));
        //删除原有权限
        adminRolePermissionMapper.delete(new LambdaQueryWrapper<AdminRolePermission>()
                .eq(AdminRolePermission::getAdminRoleId, adminRole.getId()));
        for (AdminPermission permission : permissions) {
            //给角色分配权限
            AdminRolePermission adminRolePermission = new AdminRolePermission();
            adminRolePermission.setAdminRoleId(adminRole.getId());
            adminRolePermission.setAdminPermissionId(permission.getId());
            adminRolePermissionMapper.insert(adminRolePermission);
        }
        //删除这个企业的权限缓存
        Set<String> keys = redisTemplate.keys(RedisConstants.PERMISSION + adminRole.getEnterpriseId() + "*");
        if (keys != null) {
            redisTemplate.delete(keys);
        }
        return new ReturnVO<>("权限分配成功", enterprisePermissionDto.getEnterpriseId());
    }

    @Autowired
    private AdminRolePermissionMapper adminRolePermissionMapper;

    @Autowired
    private IAdminRoleService adminRoleService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public ReturnVO<Set<AdminPermission>> getAdminUserPermission(Long adminUserId, Long enterpriseId) {
        String permission = redisTemplate.opsForValue().get(RedisConstants.PERMISSION + enterpriseId + ":" + adminUserId);
        Set<AdminPermission> list = null;
        if (StringUtils.isNotBlank(permission)) {
            JSONArray objects = JSONObject.parseArray(permission);
            return new ReturnVO("token换取用户权限信息", objects);
        }else {
            Optional<AdminUserRole> adminUserRoleOptional = adminUserRoleMapper.selectAdminUserRoleByAdminUserId(adminUserId);
            if (adminUserRoleOptional.isPresent()) {
                list = listAdminPermissionForRole(adminUserRoleOptional.get().getAdminRoleId(), enterpriseId).getData();
            }
            redisTemplate.opsForValue().set(RedisConstants.PERMISSION + enterpriseId + ":" + adminUserId,JSONObject.toJSONString(list));
        }
        return new ReturnVO("token换取用户权限信息", list);
    }

    @Autowired
    private AdminUserRoleMapper adminUserRoleMapper;

    @Override
    public ReturnVO<Set<AdminPermission>> listAdminPermissionForRole(Long adminRoleId, Long enterpriseId) {
        //查询被禁用的权限
        List<Long> disabledIds = adminPermissionDisabledMapper.selectAdminPermissionDisabledByEnterpriseId(enterpriseId);
        List<AdminPermission> adminPermissions = adminUserRoleMapper.selectPermissionByRoleId(adminRoleId, 0L);
        removePermissions(adminPermissions, disabledIds);
        for (AdminPermission adminPermission : adminPermissions) {
            List<AdminPermission> secondPermissions = adminUserRoleMapper.selectPermissionByRoleId(adminRoleId, adminPermission.getId());
            removePermissions(secondPermissions, disabledIds);
            adminPermission.setChildren(secondPermissions);
            for (AdminPermission permission : secondPermissions) {
                List<AdminPermission> buttonPermissions = adminUserRoleMapper.selectPermissionByRoleId(adminRoleId, permission.getId());
                removePermissions(buttonPermissions, disabledIds);
                permission.setChildren(buttonPermissions);
                for (AdminPermission buttonPermission : buttonPermissions) {
                    List<AdminPermission> buttonPermissionChildrens = adminUserRoleMapper.selectPermissionByRoleId(adminRoleId, buttonPermission.getId());
                    removePermissions(buttonPermissionChildrens, disabledIds);
                    buttonPermission.setChildren(buttonPermissionChildrens);
                }
            }
        }
        return new ReturnVO<>("回显角色对应权限成功", new HashSet<>(adminPermissions));
    }


    /**
     * 禁用权限
     *
     * @param adminPermissions
     * @param disabledIds
     */
    @Override
    public void removePermissions(List<AdminPermission> adminPermissions, List<Long> disabledIds) {
        List<AdminPermission> temp = Lists.newArrayList();
        for (AdminPermission adminPermission : adminPermissions) {
            for (Long disabledId : disabledIds) {
                if (adminPermission.getId().equals(disabledId)) {
                    temp.add(adminPermission);
                }
            }
        }
        //将需要禁用的直接移除
        adminPermissions.removeAll(temp);
    }
}
